#ifndef NV_NVCAPPCTL_H
#define NV_NVCAPPCTL_H

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include "nvclib.h"
#include "nvcconfig.h"

#define RECEIVE_THREAD 0x00
#define TRANSMIT_THREAD 0x01

#define MAX_PACKET_SIZE 2048
#define MAX_PACKET_NUM 2048
#define MAX_BUFFER_SIZE (MAX_PACKET_SIZE * MAX_PACKET_NUM)

#define PACKET_HEAD_LEN 12
#define PACKET_TAIL_LEN 1

#define PACKET_ENCAP_LEN (PACKET_HEAD_LEN + PACKET_TAIL_LEN)
#define FIELD_LENGTH 1
#define FIELD_TIME_S 3
#define FIELD_TIME_US 7
#define FIELD_RESERVED 11
#define FIELD_USER_DATA 12

#define PORT_CONF_FILE "port.conf"
#define LINK_CONF_FILE "link.conf"
#define CONN_CONF_FILE "conn.conf"
#define DEFAULT_IP "127.0.0.1"
#define DEFAULT_PORT 3333

#define STATUS_NORMAL 0x00
#define STATUS_STARTED 0x01
#define STATUS_RUNNING 0x02
#define STATUS_STOPPING 0x04
#define STATUS_STOPPED 0x08
#define STATUS_PAUSE 0x10
#define STATUS_RESUME 0x20
#define STATUS_ERROR 0x40

#define MSG_START 0x01
#define MSG_STOP 0x02
#define MSG_PAUSE 0x03
#define MSG_RESUME 0x04

#define WORK_THREAD_NUM 2
struct thread_state
{
	pthread_t tid;
	int status;
	pthread_cond_t cond;
	pthread_mutex_t mutex;
};

void run();
void signal_work_thread(int status);
void alloc_resource();
void free_resource();
void listener_proc();
int connect_to_server(int * sockfd);
int read_config();
int set_config();
void release_config();
int get_socket(const char * ip, unsigned short port);
char * get_socket_ip(char * hostname, struct nv_conn_config * conn);
unsigned short get_socket_port(char * hostname, struct nv_conn_config * conn);
void * receive_thread_func(void * arg);
void encap_packet(unsigned char * pack, int user_data_size);
void set_rw_pos(unsigned int * rw_pos, int inc);
int write_buffer();
int read_buffer(unsigned char ** buffer);
int send_data(int sockfd, const char * buf, unsigned int size);
void * transmit_thread_func(void * arg);
void set_thread_status(int t_index, int status);
int get_thread_status(int t_index);
void wait_thread_exit();


#endif